package Pages;

import java.util.Date;
import java.util.HashMap;
import java.util.TreeMap;
import clientMain.*;

/**
 * Item Page
 * @author Andrew Fox
 *
 */

public class ItemPage extends Page{

	StringBuffer itemName;
	double currentPrice;
	double buyNowPrice;
	int quantityAvailable;
	Date biddingEnds;
	boolean reservePriceMet=true;
	StringBuffer itemDescription=new StringBuffer();
	StringBuffer itemCondition=new StringBuffer();
	int numBids=0;
	boolean auctionExists=true;
	boolean buyNowExists=true;
	HashMap<String, StringBuffer> bidData=new HashMap<String,StringBuffer>();
	HashMap<String, StringBuffer> buyNowData=new HashMap<String, StringBuffer>();
	TreeMap<Double,StringBuffer> nextPageProbabilities=new TreeMap<Double,StringBuffer>();
	boolean ownSellingItem=false;
	int itemID;
	StringBuffer sellerName;
	int numPics=0;
	StringBuffer nextLink;


	public ItemPage(Page page){
//		super(page.url,page.lastURL,page.client);
//		this.html=page.html;
//		this.pageType=page.pageType;
		super(page.url,page.html,page.client,page.pageType);
		this.pageOpenTime=page.pageOpenTime;
		this.lastURL=page.lastURL;
		if(HTML4){
			getItemDetails();
			updateItemRating();
			//	if (client.loggedIn=true){
			bidData=getFormData("bid");
			buyNowData=getFormData("buyNow");
			//	}
		}
	}

	/**
	 * Gets the details of the item:
	 * Item Name, Number of Pictures, Item Description, Seller Name, 
	 * Current Price, Buy Now Price, Number of Bids
	 */
	public void getItemDetails(){
		if(HTML4==true){
			int start=html.indexOf("<a href=\"./index?userID=")+ "<a href=\"./index?userID=".length();
			int end=html.indexOf("&",start);
			itemID=Integer.parseInt(html.substring(start,end));
			start=html.indexOf("<label for=\"name\">")+("<label for=\"name\">").length();
			end=html.indexOf("<br />",start);
			itemName=new StringBuffer(html.subSequence(start,end));
			start=html.indexOf("Item condition: ")+("Item condition: ").length();
			end=html.indexOf("<br />",start);
			itemCondition=new StringBuffer(html.subSequence(start,end));
			start=html.indexOf("<label for=\"seller\">",end)+"<label for=\"seller\">".length();
			end=html.indexOf("</a><br />",start);
			start=html.lastIndexOf("\">",end)+"\">".length();
			sellerName=new StringBuffer(html.subSequence(start,end));
			if (sellerName.equals(client.userInfo.username)){
				ownSellingItem=true;
			}
			if (html.indexOf("The bidding on this item has finished.<BR />")==-1&&ownSellingItem==false){
				start=html.indexOf("Bidding Ends: ")+("Bidding Ends: ").length();
				end=html.indexOf("<br />",start);
				biddingEnds=StringToDate(html.substring(start,end));
				if (start!=13)
					auctionExists=true;
				start=html.indexOf("Bidding History: ")+("Bidding History: ").length();
				end=html.indexOf("<br />",start);
				numBids=Integer.parseInt(html.substring(start,end));
				start=html.indexOf("Current Price: ")+("Current Price: ").length();
				end=html.indexOf("<br />",start);
				currentPrice=Double.parseDouble(html.substring(start,end));
				start=html.indexOf("The reserve ",end)+("The reserve ").length();
				end=html.indexOf("been met",start);
				if (html.substring(start,end).equals("has"))
					reservePriceMet=true;
				else
					reservePriceMet=false;
				start=html.indexOf("Quantity: <")+("Quantity: <").length();
				start=html.indexOf("\"> (",start)+("\"> (").length();
				end=html.indexOf(" available)",start);
				quantityAvailable=Integer.parseInt(html.substring(start,end));
				start=html.indexOf("<label for=\"description\">")+("<label for=\"description\">").length();
				end=html.indexOf("<BR />",start);
				itemDescription=new StringBuffer(html.subSequence(start,end));
			}
			start=html.indexOf("<label for=\"images\">")+"<label for=\"images\">".length();
			start=html.indexOf("<label for=\"image",start)+"<label for=\"image".length();
			while(start!="<label for=\"image".length()-1){
				numPics++;
				start=html.indexOf("<label for=\"image",start)+"<label for=\"image".length();
			}
		}
	}

	/**
	 * Updates the rating for the item
	 */
	public void updateItemRating(){
		double itemRating=0;

		itemRating+=((double)getNumWords(itemName))*client.titleWordsFactor;
		itemRating+=((double)getNumWords(itemDescription))*client.descriptionWordsFactor;
		if (client.sellerRatings.containsKey(sellerName)){
			itemRating+=((double)client.sellerRatings.get(sellerName))*client.sellerRatingFactor;
		}
		itemRating+=((double)numPics)*client.numPicsFactor;

		client.itemsOfInterest.put(itemID, itemRating);
	}

	/**
	 * Gets form data for the page
	 * Separate function from one used in Page class as there can be more than one form on the page
	 * @param formType
	 * @return Returns a HashMap of the form data, (name,value) pairings
	 */
	public HashMap<String, StringBuffer> getFormData(String formType){
		String name;
		StringBuffer value;
		int start=0;
		HashMap<String, StringBuffer>data=new HashMap<String,StringBuffer>();
		start=html.indexOf("<form name=\""+formType);
		if (start!=-1){
			start=html.indexOf("POST",start)+("POST").length();
			start=html.indexOf("\" name=\"",start)+("\" name=\"").length();

			int end=start;
			int formEnd=html.indexOf("</form>",start);
			while(start<formEnd&&start!=5){
				end=html.indexOf("\"",start);
				name=html.substring(start,end);
				if (html.charAt(end+1)=='>'){
					end=html.indexOf("\" SELECTED");
					start=html.lastIndexOf("value=\"",end)+("value=\"").length();
				}
				else{
					start=html.indexOf("value=\"",end)+("value=\"").length();
					end=html.indexOf("\"",start);
				}
				value=new StringBuffer(html.subSequence(start,end));
				start=html.indexOf("name=\"",end)+("name=\"").length();
				data.put(name,value);
			}
		}
		else{
			if (formType.equals("bid"))
				auctionExists=false;
			if (formType.equals("buyNow"))
				buyNowExists=false;			
		}
		return data;
	}

	/**
	 * Determines the next link to go to in the application
	 * @return the URL or HTML of the next link, depending on whether
	 * 		   the previous entry contained a form or not
	 */
	public StringBuffer makeDecision() throws Exception{
		StringBuffer nextPage=new StringBuffer();

		if (html.indexOf("The bidding on this item has finished.")==-1){
			updateProbabilites();

			nextLink=getRandomStringFromDist(nextPageProbabilities);
		}
		else
			nextLink=new StringBuffer("back");
		if(verbose)System.out.println("Next Link: "+nextLink);
		// Think Time
		try{Thread.sleep(getThinkTime());}
		catch(InterruptedException e){
			e.printStackTrace();
		}

		if(HTML4){
		if (nextLink.equals("bid")){
			bidData.put("quantity", new StringBuffer("1"));
			bidData.put("bid", new StringBuffer(Double.toString(currentPrice*1.1+0.01)));
			bidData.put("maxBid", new StringBuffer(Double.toString(currentPrice*1.1+0.01)));

			nextPage=doSubmit3(runSettings.rootURL.append("/viewitem?"),bidData,client);
		}
		else if(nextLink.equals("buyNow")){
			System.out.println(buyNowData);
			nextPage=doSubmit3(runSettings.rootURL.append("/buyitem?"),buyNowData,client);
		}
		else if (nextLink.equals("back")){
			nextPage=lastURL;
		}
		else{
			int end=html.indexOf("\">"+nextLink);
			int start=html.lastIndexOf("<a href=\".",end)+10;
			nextPage=runSettings.rootURL.append(html.subSequence(start,end));

		}
		}
		else{
			if(nextLink.equals("bid")){
			HashMap<String,StringBuffer> bidData5=new HashMap<String,StringBuffer>();

			StringBuffer itemID=new StringBuffer(this.url.substring(this.url.lastIndexOf("=")+1));
			bidData5.put("userID",client.userInfo.userID);
			bidData5.put("itemID", itemID);
			double bid=5;
			if(client.currentBids.containsKey(itemID))
			bid=client.currentBids.get(itemID)*1.1+0.1;
			client.currentBids.put(Integer.parseInt(itemID.toString()), bid);
			bidData5.put("bid",new StringBuffer(Double.toString(bid)));
			bidData5.put("maxBid", new StringBuffer(Double.toString(bid*3)));
			bidData5.put("quantity", new StringBuffer("1"));
			nextPage=runSettings.rootURL.append("/bid?").append(createURL(bidData5));
			}
			else if(nextLink.equals("buyNow")){
				HashMap<String,StringBuffer> buyNowData5=new HashMap<String,StringBuffer>();
				StringBuffer itemID=new StringBuffer(this.url.substring(this.url.lastIndexOf("=")+1));
				buyNowData5.put("userID",client.userInfo.userID);
				buyNowData5.put("itemID", itemID);
				buyNowData5.put("quantity", new StringBuffer("1"));
				buyNowData5.put("accountID", new StringBuffer("0"));
				nextPage=runSettings.rootURL.append("/buyitem?").append(createURL(buyNowData5));
			}
			else if(nextLink.equals("My Account")){
				nextPage=runSettings.rootURL.append("/myaccount");				
			}
			
		}

		return nextPage;

	}



	/**
	 * Updates the probabilities of which page to transition to
	 */
	public void updateProbabilites(){
		double probSum=1;

		double bidProb=.35;
		double buyNowProb=.35;
		double homeProb=0;
		double browseProb=0.1;
		double sellProb=0;
		double myAccountProb=.1;
		double logOutProb=0.1;
		double closeWindowProb=0.0;

		TreeMap<StringBuffer,Double>allOptions=new TreeMap<StringBuffer,Double>();

		if (auctionExists==false)
			bidProb=0;
		if (buyNowExists==false)
			buyNowProb=0;

		if(HTML4==false){
			bidProb=.4;
			buyNowProb=.4;
			homeProb=0;
			browseProb=0;
			sellProb=0;
			myAccountProb=.2;
			logOutProb=0.0;
			closeWindowProb=0.0;
		}

		allOptions.put(new StringBuffer("bid"),bidProb);
		allOptions.put(new StringBuffer("buyNow"), buyNowProb);
		allOptions.put(new StringBuffer("Home"), homeProb);
		allOptions.put(new StringBuffer("Browse"), browseProb);
		allOptions.put(new StringBuffer("Sell"), sellProb);
		allOptions.put(new StringBuffer("My Account"), myAccountProb);
		allOptions.put(new StringBuffer("Log out"), logOutProb);
		allOptions.put(new StringBuffer("Close"), closeWindowProb);

		double actualProbSum=0;
		for (StringBuffer m:allOptions.keySet()){
			actualProbSum+=allOptions.get(m);
		}
		for (StringBuffer m:allOptions.keySet()){
			nextPageProbabilities.put(probSum, m);
			probSum-=allOptions.get(m)/actualProbSum;
		}

	}

	/**
	 * Determines the think time before going to the next page.
	 * Deducts from the think time the amount of time since the 
	 * page opened until this calculation is performed
	 * @return Think time in ms
	 */
	public int getThinkTime(){
		int thinkTime=(int)expDist(initialThinkTime);
		if (nextLink.equals("bid")){
			thinkTime+=(int)expDist(10000);
		}
		else if(nextLink.equals("buy")){
			thinkTime+=(int)expDist(10000);
		}
		else if (nextLink.equals("back")){
			thinkTime+=(int)expDist(3000);
		}
		else{
			thinkTime+=(int)expDist(7000);
		}

		if (verbose)System.out.println("User: "+client.userInfo.username+" - Think Time: "+thinkTime+" ms");
		return (int) ((thinkTime-(new Date().getTime()-pageOpenTime))/runSettings.thinkTimeSpeedUpFactor);
	}

}